package run.halo.app.security.filter;

import java.io.IOException;
import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import run.halo.app.cache.AbstractStringCacheStore;
import run.halo.app.config.properties.HaloProperties;
import run.halo.app.model.support.FrontConstant;
import run.halo.app.model.support.HaloConst;
import run.halo.app.security.handler.ContentAuthenticationFailureHandler;
import run.halo.app.security.service.OneTimeTokenService;
import run.halo.app.service.OptionService;
import run.halo.app.utils.HaloUtils;

/**
 * Content filter
 *
 * @author johnniang
 * @date 19-5-6
 */
@Component
@Order(-1)
public class ContentFilter extends AbstractAuthenticationFilter {

    @Resource
     private  StringRedisTemplate stringRedisTemplate;;
    public static ThreadLocal<Boolean> isLogin = new ThreadLocal<>();

    public ContentFilter(HaloProperties haloProperties,
        OptionService optionService,
        AbstractStringCacheStore cacheStore,
        OneTimeTokenService oneTimeTokenService) {
        super(haloProperties, optionService, cacheStore, oneTimeTokenService);

        addUrlPatterns("/**");

        String adminPattern = HaloUtils.ensureBoth(haloProperties.getAdminPath(), "/") + "**";
        addExcludeUrlPatterns(
            adminPattern,
            "/api/**",
            "/install",
            "/version",
            "/js/**",
            "/css/**");

        // set failure handler
        setFailureHandler(new ContentAuthenticationFailureHandler());
    }

    @Override
    protected String getTokenFromRequest(HttpServletRequest request) {
        return null;
    }

    @Override
    protected void doAuthenticate(HttpServletRequest request, HttpServletResponse response,
        FilterChain filterChain) throws ServletException, IOException {
        // Do nothing
        // create session
        request.getSession(true);
        //校验用户登录状态
        checkLogin(request);

        filterChain.doFilter(request, response);
    }

    /**
     * 校验token方法值，判断是否登录
     * @param request
     */
    private void checkLogin(HttpServletRequest request){
        //默认未登录
        isLogin.set(false);
        Cookie[] cookies = request.getCookies();
        if(null == cookies){
            return;
        }

        for(Cookie cookie : cookies){
            if(HaloConst.TOKEN_COOKIE_NAME.equals(cookie.getName())){
                //获取token值
                String value = cookie.getValue();
                if(!StringUtils.isEmpty(value) ){
                    String key = FrontConstant.REDIS_CUSTOMER_AUTH_TOKEN + value;
                    Boolean aBoolean =
                        stringRedisTemplate.hasKey(key);
                    isLogin.set(aBoolean);
                }
            }
        }
    }
}
